home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 4_0 / STANDALO / SPROING! / SPROING_.C next >
C/C++ Source or Header  |  1990-10-27  |  4KB  |  147 lines

  1. /*_________________________________________________________________________
  2.  
  3.         Sproing - A Springy Cursor VBL 
  4.         
  5.         October 1990
  6.         
  7.         ⌐1990 Scott Armitage
  8.     
  9.         Written for Think C
  10.  
  11.     This VBL will put values into the MouseOffset system global to cause
  12.     the mouse to move relative to its normal position.
  13.     The offset used here is a filtered version of the mouse's position.
  14.     This gives a "springy" effect to the cursor movement.
  15.     Depressing the Caps Lock key will disable the filtering action.
  16.     
  17.     This code uses undocumented system globals and could break someday,
  18.     but, hey, what's a good hack that doesn't live a bit dangerously?
  19.     
  20.     Floating point cannot be used here, apparently because the FP68K
  21.     trap is not reentrant (i.e. when an application does a SANE operation
  22.     and the VBL interrupts it and does a SANE operation too... KaBoom).
  23.     To circumvent this and still get smooth filtering action,
  24.     all mouse locations are expressed in fixed point format.
  25.     
  26.     This VBL can be installed with an INIT or with an installer application.
  27.     
  28. _________________________________________________________________________*/
  29.  
  30. #include "VRetraceMgr.h"
  31.  
  32.     /* the system globals we use */
  33. extern Boolean CrsrNew : 0x8CE;
  34. extern Point MouseOffset : 0x8DA;
  35. extern Point mTemp : 0x828;
  36. extern char keyMap[8] : 0x174;
  37.  
  38.     /* some constants for adjusting dynamics */
  39. /* slugishness (10=quick, 1000=painfully slow) */
  40. #define slugishness 50
  41. /* offset per movement of cursor (1 = dull, 100 = touchy) */
  42. #define sensitivity    10
  43.  
  44.     /* our globals */
  45. Fixed newX, newY;
  46. Fixed vx, vy;
  47. unsigned long me;
  48.  
  49.     /* function prototypes */
  50. header(void);
  51. __GetA4(void);
  52. main(void);
  53. getNewOffset(int* x, int* y);
  54.  
  55. /*_____________________________________________________________________*/
  56. /* our custom header */
  57. header()
  58. {
  59.     asm {
  60.         dc.l    0                            /* a place to store A4 */
  61.         move.l a0, d0                        /* save a0 (vbl ptr) */
  62.         lea header, a0                        /* for SetUpA4() */
  63.         jmp main
  64.     }
  65. }
  66.  
  67. #include "SetUpA4.h"
  68.  
  69. /*_____________________________________________________________________*/
  70. main()
  71. {
  72.     VBLTask* myVBL;
  73.     int xOfs, yOfs;
  74.     
  75.     RememberA0();                                /* save a0 */
  76.     SetUpA4();                                    /* set a4 */
  77.     
  78.     asm {
  79.         move.l d0, myVBL                        /* a ptr to vbl task */
  80.     }
  81.     
  82.     if (me != 'Scot') {                            /* first time ? */
  83.         newX = Long2Fix(mTemp.h);                /* init globals */
  84.         newY = Long2Fix(mTemp.v);
  85.         vx = 0;
  86.         vy = 0;
  87.         me = 'Scot';
  88.     }
  89.         /* test caps lock key - GetKeys can't be used in a VBL */
  90.     if (keyMap[7] & 0x02) {                        /* caps lock down ? */
  91.         newX = Long2Fix(mTemp.h);                /* restore things to normal */
  92.         newY = Long2Fix(mTemp.v);
  93.         vx = 0;
  94.         vy = 0;
  95.         MouseOffset.h = 0;
  96.         MouseOffset.v = 0;
  97.         CrsrNew = true;
  98.     }
  99.     else {                                        /* caps lock up */
  100.         getNewOffset(&xOfs, &yOfs);                /* do our filtering */
  101.         
  102.         MouseOffset.h = xOfs;                    /* use our mouse offset correction */
  103.         MouseOffset.v = yOfs;
  104.         CrsrNew = true;                            /* tell 'em we changed it */
  105.     }
  106.  
  107.     myVBL->vblCount = 1;                        /* see ya' next time */
  108.     
  109.     RestoreA4();
  110. }
  111.  
  112. /*_____________________________________________________________________
  113.     This routine computes a new offset for the cursor.
  114.     It uses a "rubber band" model.
  115.     It first factors in the velocity of the cursor to give the 
  116.     illusion of inertia.  Then it computes the distance
  117.     from the "real" cursor position to the offset position.
  118.     This distance is used to compute the force which the rubber
  119.     band exerts to pull the cursor back into position.
  120. _____________________________________________________________________*/
  121. getNewOffset(xOfs, yOfs)
  122. int *xOfs, *yOfs;
  123. {
  124.     Fixed oldX, oldY, deltaX, deltaY, xOffset, yOffset;
  125.  
  126.     oldX = newX;                                /* save old locations */
  127.     oldY = newY;
  128.  
  129.     newX += vx;                                    /* add effect of inertia */
  130.     newY += vy;
  131.     
  132.     deltaX = newX - Long2Fix(mTemp.h);            /* find distance to real cursor */
  133.     deltaY = newY - Long2Fix(mTemp.v);
  134.                                                 /* add force proportional to distance */
  135.     xOffset = - sensitivity * deltaX / 10;
  136.     yOffset = - sensitivity * deltaY / 10;
  137.     
  138.     newX += xOffset/slugishness;                /* adjust how much we'll respond */
  139.     newY += yOffset/slugishness;                /*   to the force */
  140.  
  141.     vx = newX - oldX;                            /* get velocity for next time */
  142.     vy = newY - oldY;
  143.  
  144.     *xOfs = Fix2Long(xOffset);                    /* return the answers */
  145.     *yOfs = Fix2Long(yOffset);
  146. }
  147.